package com.example.checkingin;

import android.app.TimePickerDialog;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.TimePicker;
import android.app.AlertDialog; // 1. 增加这个 import


import androidx.appcompat.app.AppCompatActivity;


import java.util.Calendar;
import java.util.Locale;



public class Login extends AppCompatActivity {

    // 1. 声明所有“骨架”里的控件
    // ---------------------------------
    // 用于显示和选择时间的 TextView
    private TextView tv_start_time, tv_end_time;
    // 用于显示最终结果的 TextView
    private TextView tv_result;


    // "计算工时"（青铜需求）按钮
    private Button btn_calculate;

    // 6个加班（白银需求）按钮
    private Button btn_ot_0_5, btn_ot_1, btn_ot_2, btn_ot_2_5, btn_ot_3, btn_ot_3_5;
    // ---------------------------------


    // 2. 声明所需的数据
    // ---------------------------------
    // 我们不能只依赖 TextView 上的 "09:00" 字符串来计算
    // 必须使用 Calendar 对象来“真正”存储用户选择的时间

    private Calendar startTimeCalendar = null;
    private Calendar endTimeCalendar = null;

    // 核心规则常量
    private static final int LUNCH_BREAK_MINUTES = 45;
    // 标准“纯”工作时长（8小时）
    private static final int STANDARD_PURE_WORK_MINUTES = 8 * 60; // 480 分钟
    // 修复：标准“出勤”总时长（8h45m，含午休，用于白银需求计算）
    private static final int STANDARD_ATTENDANCE_DURATION_MINUTES = (8 * 60) + LUNCH_BREAK_MINUTES; // 8h45m，即 525 分钟


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 告诉 Java 加载哪个 XML 布局文件
        setContentView(R.layout.activity_login);

        // 3. 在 onCreate 里连接控件和绑定事件
        initViews();
        initListeners();
    }

    /**
     * 专门用于“连接”XML控件 (findViewById)
     */
    private void initViews() {
        // 连接 TextView
        tv_start_time = findViewById(R.id.tv_start_time);
        tv_end_time = findViewById(R.id.tv_end_time);
        tv_result = findViewById(R.id.tv_result);

        // 连接“计算”按钮
        btn_calculate = findViewById(R.id.btn_calculate);

        // 连接“加班”按钮
        btn_ot_0_5 = findViewById(R.id.btn_ot_0_5);
        btn_ot_1 = findViewById(R.id.btn_ot_1);
        btn_ot_2 = findViewById(R.id.btn_ot_2);
        btn_ot_2_5 = findViewById(R.id.btn_ot_2_5);
        btn_ot_3 = findViewById(R.id.btn_ot_3);
        btn_ot_3_5 = findViewById(R.id.btn_ot_3_5);
    }

    /**
     * 专门用于给控件“绑定”点击事件 (setOnClickListener)
     */
    private void initListeners() {

        // --- 核心功能一：时间选择 ---
        // (null 检查，提高代码健壮性)
        if (tv_start_time != null) {
            tv_start_time.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // 点击时，显示时间选择器对话框，isStartTime=true 表示是为“上班时间”设置
                    showTimePickerDialog(true);
                }
            });
        }
        if (tv_end_time != null) {
            tv_end_time.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    showTimePickerDialog(false);
                }
            });
        }


        // --- 核心功能二：“白银”需求（自动算下班） ---
        // 我们给所有加班按钮设置点击事件
        // 它们都调用同一个处理方法 handleOvertimeClick，只是传入的加班小时数不同
        // (增加 null 检查)
        if (btn_ot_0_5 != null) btn_ot_0_5.setOnClickListener(v -> handleOvertimeClick(0.5));
        if (btn_ot_1 != null) btn_ot_1.setOnClickListener(v -> handleOvertimeClick(1.0));
        if (btn_ot_2 != null) btn_ot_2.setOnClickListener(v -> handleOvertimeClick(2.0));
        if (btn_ot_2_5 != null) btn_ot_2_5.setOnClickListener(v -> handleOvertimeClick(2.5));
        if (btn_ot_3 != null) btn_ot_3.setOnClickListener(v -> handleOvertimeClick(3.0));
        if (btn_ot_3_5 != null) btn_ot_3_5.setOnClickListener(v -> handleOvertimeClick(3.5));


        // --- 核心功能三：“青铜”需求（分析考勤） ---
        if (btn_calculate != null) {
            btn_calculate.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // 点击“计算工时”时，调用我们自己的分析方法
                    calculateAttendance();
                }
            });
        }
    }

    /**
     * 核心功能一：显示时间选择对话框
     * @param isStartTime 是为“上班时间”设置(true)，还是“下班时间”(false)
     */
    private void showTimePickerDialog(final boolean isStartTime) {
        // 1. 决定对话框默认显示哪个时间
        // 如果用户之前选过 (Calendar != null)，就显示那个时间；
        // 如果没选过 (null)，就显示当前时间。
        Calendar calendarToShow;
        if (isStartTime && startTimeCalendar != null) {
            calendarToShow = startTimeCalendar;
        } else if (!isStartTime && endTimeCalendar != null) {
            calendarToShow = endTimeCalendar;
        } else {
            calendarToShow = Calendar.getInstance();
        }

        int hour = calendarToShow.get(Calendar.HOUR_OF_DAY);
        int minute = calendarToShow.get(Calendar.MINUTE);

        // 2. 创建一个时间选择监听器
        TimePickerDialog.OnTimeSetListener timeSetListener = new TimePickerDialog.OnTimeSetListener() {
            @Override
            public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
                // 3. 当用户选好时间后，执行这里
                Calendar selectedTime = Calendar.getInstance();
                selectedTime.set(Calendar.HOUR_OF_DAY, hourOfDay);
                selectedTime.set(Calendar.MINUTE, minute);
                selectedTime.set(Calendar.SECOND, 0); // 秒数清零，方便计算

                // 4. 更新我们的“数据” (Calendar对象) 和“界面” (TextView)
                if (isStartTime) {
                    startTimeCalendar = selectedTime;
                    updateTimeText(tv_start_time, startTimeCalendar);

                    // --- 方案 2（你选的）：自动计算不加班的下班时间 ---
                    // 在选完上班时间后，立即触发一次加班为 0 的计算
                    // 这会给 endTimeCalendar 赋值，并更新 tv_end_time
                    handleOvertimeClick(0.0);
                    // ------------------------------------

                } else {
                    endTimeCalendar = selectedTime;
                    updateTimeText(tv_end_time, endTimeCalendar);
                }
            }
        };

        // 5. 创建并显示对话框
        // 2. 最小化修改：换一个构造函数，传入一个主题来强制使用 "spinner" (滑动) 样式
        new TimePickerDialog(Login.this,
                AlertDialog.THEME_HOLO_LIGHT, // 使用HOLO亮色主题，这将强制 spinner 模式
                timeSetListener,
                hour,
                minute,
                true).show(); // true 表示 24 小时制
    }

    /**
     * 辅助方法：更新 TextView 上的时间显示 (例如 09:05)
     */
    private void updateTimeText(TextView tv, Calendar cal) {
        String timeStr = String.format(Locale.getDefault(),
                "%02d:%02d",
                cal.get(Calendar.HOUR_OF_DAY),
                cal.get(Calendar.MINUTE));
        tv.setText(timeStr);
    }

    /**
     * 核心功能二：“白银”需求的处理逻辑
     * @param overtimeHours 用户点击的加班小时数 (例如 0.5, 1.0)
     */
    private void handleOvertimeClick(double overtimeHours) {
        // 1. 检查是否选了上班时间
        if (startTimeCalendar == null) {
            tv_result.setText("错误：请先选择上班时间");
            return;
        }

        // 2. 获取“修正后”的上班时间
        // (例如 7:15 上班，按 7:30 算)
        Calendar normalizedStart = getNormalizedStart(startTimeCalendar);

        // 3. 计算总共需要工作多少分钟
        // 修复：使用“标准出勤总时长”(525分钟) 来计算
        int overtimeMinutes = (int) (overtimeHours * 60);
        int totalWorkMinutes = STANDARD_ATTENDANCE_DURATION_MINUTES + overtimeMinutes;

        // 4. 在“修正后”的上班时间基础上，加上总工时
        // (注意：这里用 clone() 是为了不修改 normalizedStart 原对象)
        Calendar calculatedEndTime = (Calendar) normalizedStart.clone();
        calculatedEndTime.add(Calendar.MINUTE, totalWorkMinutes);

        // 5. 更新“下班时间”的数据和界面
        endTimeCalendar = calculatedEndTime;
        updateTimeText(tv_end_time, endTimeCalendar);

        // 6. 给用户一个友好提示
        // 修复：当加班为0时，显示不同的提示文本
        if (overtimeHours == 0.0) {
            tv_result.setText(String.format(Locale.getDefault(),
                    "已按上班时间 %s，自动计算（不加班）的下班时间。",
                    tv_start_time.getText()));
        } else {
            tv_result.setText(String.format(Locale.getDefault(),
                    "已按上班时间 %s，自动计算加班 %.1fh 的下班时间。",
                    tv_start_time.getText(),
                    overtimeHours));
        }
    }


    /**
     * 核心功能三：“青铜”需求的处理逻辑
     */
    private void calculateAttendance() {
        // 1. 检查数据是否齐全
        if (startTimeCalendar == null || endTimeCalendar == null) {
            tv_result.setText("错误：请先选择上班时间和下班时间");
            return;
        }

        // 2. 检查下班时间是否晚于上班时间
        if (!endTimeCalendar.after(startTimeCalendar)) {
            tv_result.setText("错误：下班时间必须晚于上班时间");
            return;
        }

        // 3. 准备一个 StringBuilder 来拼接最终的分析结果
        StringBuilder resultBuilder = new StringBuilder();
        resultBuilder.append("--- 考勤分析结果 ---\n\n");

        // 4. 分析是否迟到（用“实际”上班时间判断）
        // 迟到标准：9:30:00
        Calendar lateThreshold = (Calendar) startTimeCalendar.clone();
        lateThreshold.set(Calendar.HOUR_OF_DAY, 9);
        lateThreshold.set(Calendar.MINUTE, 30);
        lateThreshold.set(Calendar.SECOND, 0);

        if (startTimeCalendar.after(lateThreshold)) {
            resultBuilder.append("【状态：迟到】\n");
        } else {
            resultBuilder.append("【状态：正常】\n");
        }

        // 5. 计算有效工时（用“修正后”的上班时间计算）
        Calendar normalizedStart = getNormalizedStart(startTimeCalendar);

        // 6. 计算总分钟差
        long diffInMillis = endTimeCalendar.getTimeInMillis() - normalizedStart.getTimeInMillis();
        long totalMinutes = diffInMillis / (60 * 1000); // 毫秒转分钟

        // 7. 减去 45 分钟午休，得到“实际工作分钟数”
        long actualWorkMinutes = totalMinutes - LUNCH_BREAK_MINUTES;

        resultBuilder.append(String.format(Locale.getDefault(),
                "有效工作时长：%d 分钟\n",
                actualWorkMinutes));

        // 8. 分析是否满勤 / 早退 / 加班
        // 修复：必须用“纯工作时间”(actualWorkMinutes) 对比 “标准纯工作时间”(STANDARD_PURE_WORK_MINUTES)
        if (actualWorkMinutes >= STANDARD_PURE_WORK_MINUTES) {
            // 8.1 工时达标，计算加班
            resultBuilder.append("【工时：达标】\n");

            // 修复：加班分钟数 = 实际纯工作 - 标准纯工作 (e.g. 540 - 480 = 60)
            long overtimeMinutes = actualWorkMinutes - STANDARD_PURE_WORK_MINUTES;

            // 规则：加班最小计算单位为15min，向下取整
            // (例如 20 分钟 -> 15 分钟, 10 分钟 -> 0 分钟)
            long validOtMinutes = (long) (Math.floor(overtimeMinutes / 15.0) * 15);

            // 分钟转小时
            double otHours = validOtMinutes / 60.0;

            if (validOtMinutes > 0) {
                resultBuilder.append(String.format(Locale.getDefault(),
                        "有效加班：%.2f 小时 (%d 分钟)\n",
                        otHours,
                        validOtMinutes));
            } else {
                resultBuilder.append("有效加班：0 小时\n");
            }

        } else {
            // 8.2 工时未达标
            // 修复：缺勤分钟数 = 标准纯工作 - 实际纯工作
            long minutesShort = STANDARD_PURE_WORK_MINUTES - actualWorkMinutes;
            resultBuilder.append(String.format(Locale.getDefault(),
                    "【工时：未满勤 (缺 %d 分钟)】\n",
                    minutesShort));
        }

        // 9. 最终显示结果
        tv_result.setText(resultBuilder.toString());
    }

    /**
     * 辅助方法：获取“修正后”的上班时间
     * 规则：早于 7:30，按 7:30 算。
     * @param originalStart 用户“实际”选择的上班时间
     * @return 用于计算的“标准”上班时间
     */
    private Calendar getNormalizedStart(Calendar originalStart) {
        // 1. 必须 clone()，否则会修改掉用户选的“实际”时间
        Calendar normalized = (Calendar) originalStart.clone();

        // 2. 建立 7:30 的标准线
        Calendar earlyThreshold = (Calendar) originalStart.clone();
        earlyThreshold.set(Calendar.HOUR_OF_DAY, 7);
        earlyThreshold.set(Calendar.MINUTE, 30);
        earlyThreshold.set(Calendar.SECOND, 0);

        // 3. 如果上班时间早于 7:30
        if (normalized.before(earlyThreshold)) {
            // 强行修正为 7:30
            normalized.set(Calendar.HOUR_OF_DAY, 7);
            normalized.set(Calendar.MINUTE, 30);
            normalized.set(Calendar.SECOND, 0);
        }

        // 4. 返回修正后（或无需修正）的时间
        return normalized;
    }
}


